/**
 * 最简单的例子
 * 参考：https://github.com/kenberkeley/redux-simple-tutorial
 */
import { createStore } from 'redux'


/**
 * Action Creators 
 * Action Creator 可以是同步的，也可以是异步的
 * 顾名思义，Action Creator 是 action 的创造者，本质上就是一个函数，返回值是一个 action（对象）
 * 通俗点讲，Action Creator 用于绑定到用户的操作（点击按钮等），其返回值 action 用于之后的 dispatch(action)
*/
function inc() {
    return { type: 'INCREMENT' };
}

function dec() {
    return { type: 'DECREMENT' };
}

var id = 1
function addTodo(content) {
    return {
        type: 'ADD_TODO',
        payload: {
            id: id++,
            content: content, // 待办事项内容
            completed: false  // 是否完成的标识
        }
    }
}


/**
 * Reducer
 * Reducer 必须是同步的纯函数
 * 用户每次 dispatch(action) 后，都会触发 reducer 的执行
 * reducer 的实质是一个函数，根据 action.type 来更新 state 并返回 nextState
 * 最后会用 reducer 的返回值 nextState 完全替换掉原来的 state
 * 注意：上面的这个 “更新” 并不是指 reducer 可以直接对 state 进行修改
 * Redux 规定，须先复制一份 state，在副本 nextState 上进行修改操作
 * 例如，可以使用 lodash 的 cloneDeep，也可以使用 Object.assign / map / filter/ ... 等返回副本的函数
 */
function reducer(state, action) {
    // 首次调用本函数时设置初始 state
    state = state || {
        counter: 0,
        todos: []
    };

    switch (action.type) {
        case 'INCREMENT':
            return Object.assign({}, state, { counter: state.counter + 1 });
        case 'DECREMENT':
            //return { counter: state.counter - 1 };
            return Object.assign({}, state, { counter: state.counter - 1 });
        case "ADD_TODO":
            var nextState = Object.assign({}, state, { todos: [...state.todos, action.payload] })
            return nextState;
        default:
            return state; // 无论如何都返回一个 state
    }
}


/**
 * Store
 * state 是应用的状态，一般本质上是一个普通对象
 * store 是应用状态 state 的管理者，包含下列四个函数：
 * getState() # 获取整个 state
 * dispatch(action) # ※ 触发 state 改变的【唯一途径】※
 * subscribe(listener) # 您可以理解成是 DOM 中的 addEventListener
 * replaceReducer(nextReducer) # 一般在 Webpack Code-Splitting 按需加载的时候用
 * 二者的关系是：state = store.getState()
 * Redux 规定，一个应用只应有一个单一的 store，其管理着唯一的应用状态 state
 * Redux 还规定，不能直接修改应用的状态 state，也就是说，下面的行为是不允许的：
 * var state = store.getState()
 * state.counter = state.counter + 1 // 禁止在业务逻辑中直接修改 state
 * 若要改变 state，必须 dispatch 一个 action，这是修改应用状态的不二法门
 * 现在您只需要记住 action 只是一个包含 type 属性的普通对象即
 * 例如 { type: 'INCREMENT' }
 * 上面提到，state 是通过 store.getState() 获取，那么 store 又是怎么来的呢？
 * 想生成一个 store，我们需要调用 Redux 的 createStore：
 * import { createStore } from 'redux'
 * ...
 * const store = createStore(reducer, initialState) // store 是靠传入 reducer 生成的哦！
 */
var store = createStore(reducer);


/**
 * dispatch
 */
console.log(store.getState()); // { counter: 0 }

store.dispatch(inc());
console.log(store.getState()); // { counter: 1 }

store.dispatch(inc());
console.log(store.getState()); // { counter: 2 }

store.dispatch(dec());
console.log(store.getState()); // { counter: 1 }

store.dispatch(addTodo("abc"));
console.log(store.getState());